import { OnInit, Component, forwardRef, AfterViewInit, OnChanges, Input, ViewChild, ElementRef } from '@angular/core'
import { NG_VALUE_ACCESSOR, ControlValueAccessor, FormGroup } from '@angular/forms'
import { onlyNumberReg, getCertainNumDecimalNumberReg } from 'app/utils/contraints'

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CustomInputComponent),
  multi: true,
}

@Component({
  templateUrl: './custom-input.component.html',
  selector: 'app-custom-input',
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR],
})
export class CustomInputComponent implements OnInit, ControlValueAccessor, AfterViewInit, OnChanges {
  @Input() type: 'text' | 'number'

  /** 小数位数 */
  @Input() precision: number

  /** 后缀 */
  @Input() addOnAfter: string

  /** 是否editable */
  @Input() disabled = false

  @ViewChild('input') inputRef: ElementRef

  private innerValue: any = ''

  propagateChange = (_: any) => {}

  writeValue(value: any): void {
    this.innerValue = value
  }

  registerOnChange(fn: any): void {
    this.propagateChange = fn
  }

  registerOnTouched(fn: any): void {}

  setDisabledState?(isDisabled: boolean): void {}

  get value(): any {
    return this.innerValue
  }

  set value(v: any) {
    if (v !== this.innerValue) {
      this.innerValue = v
    }
  }

  constructor() {
  }

  ngOnInit() {
    console.log(this.precision)
  }

  ngAfterViewInit() {}

  ngOnChanges() {}

  onChange(e: Event, value: any) {
    if (value === '') {
      this.setValue(value)
      this.inputRef.nativeElement.value = this.innerValue
      return
    }
    if (this.type === 'number') {
      this.parseAsNumber(value)
    } else {
      this.setValue(value)
    }
    this.inputRef.nativeElement.value = this.innerValue
  }

  private parseAsNumber(value: string) {
    if (!this.precision || this.precision === 0) {
      /** 整数 */
      if (onlyNumberReg.test(value.toString())) {
        this.setValue(parseInt(value, 10))
      }
    } else {
      /** 指定小数位数 */
      const reg = getCertainNumDecimalNumberReg(this.precision)
      const val = value.toString()
      if (reg.test(val)) {
        this.setValue(val)
      }
    }
  }

  private setValue(value): void {
    this.innerValue = value
    this.propagateChange(this.innerValue)
  }
}
